package com.lineage.server.datatables;

import com.lineage.DatabaseFactory;
import com.lineage.server.datatables.sql.CharBuffTable;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1PolyMorph;
import com.lineage.server.serverpackets.S_HPUpdate;
import com.lineage.server.serverpackets.S_MPUpdate;
import com.lineage.server.serverpackets.S_OwnCharAttrDef;
import com.lineage.server.serverpackets.S_OwnCharStatus;
import com.lineage.server.serverpackets.S_OwnCharStatus2;
import com.lineage.server.serverpackets.S_SPMR;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SkillSound;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1ItemUseEX;
import com.lineage.server.utils.BinaryOutputStream;
import com.lineage.server.utils.SQLUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ItemUseEXTable {
  private static final Log _log = LogFactory.getLog(ItemUseEXTable.class);
  
  public static final Map<Integer, L1ItemUseEX> _list = new HashMap<>();
  
  public static final Map<Integer, ArrayList<Integer>> _type = new HashMap<>();
  
  private static final HashMap<Integer, BinaryOutputStream> _os = new HashMap<>();
  
  private static ItemUseEXTable _instance;
  
  public static ItemUseEXTable get() {
    if (_instance == null)
      _instance = new ItemUseEXTable(); 
    return _instance;
  }
  
  private ItemUseEXTable() {
    load();
  }
  
  private void load() {
    Connection co = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      co = DatabaseFactory.get().getConnection();
      pstm = co.prepareStatement("SELECT * FROM `w_道具状态`");
      rs = pstm.executeQuery();
      while (rs.next()) {
        int item_id = rs.getInt("道具编号");
        String itemName = rs.getString("道具名称");
        String Message = rs.getString("注解");
        int type = rs.getInt("道具类型");
        int type_mod = rs.getInt("道具类型效果覆盖");
        int buff_time = rs.getInt("效果秒数");
        int buff_gfx = rs.getInt("特效");
        boolean buff_save = rs.getBoolean("特效是否保存");
        int poly = rs.getInt("变身编号");
        int cancellation = rs.getInt("cancellation");
        int add_str = rs.getInt("增加力量");
        int add_dex = rs.getInt("增加敏捷");
        int add_con = rs.getInt("增加体质");
        int add_int = rs.getInt("增加智力");
        int add_wis = rs.getInt("增加精神");
        int add_cha = rs.getInt("增加魅力");
        int add_ac = rs.getInt("增加防御");
        int add_hp = rs.getInt("增加血量");
        int add_mp = rs.getInt("增加魔量");
        int add_hpr = rs.getInt("增加回血量");
        int add_mpr = rs.getInt("增加回魔量");
        int add_dmg = rs.getInt("增加近战伤害");
        int add_hit = rs.getInt("增加近战命中");
        int add_bow_dmg = rs.getInt("增加远攻伤害");
        int add_bow_hit = rs.getInt("增加远攻命中");
        int add_dmg_r = rs.getInt("增加减免物理伤害");
        int add_magic_r = rs.getInt("增加减免魔法伤害");
        int add_mr = rs.getInt("增加抗魔");
        int add_sp = rs.getInt("增加魔攻");
        int add_fire = rs.getInt("增加抗火属性");
        int add_wind = rs.getInt("增加抗风属性");
        int add_earth = rs.getInt("增加抗地属性");
        int add_water = rs.getInt("增加抗水属性");
        int add_stun = rs.getInt("增加昏迷耐性");
        int add_stone = rs.getInt("增加石化耐性");
        int add_sleep = rs.getInt("增加睡眠耐性");
        int add_freeze = rs.getInt("增加寒冰耐性");
        int add_sustain = rs.getInt("增加支撑耐性");
        int add_blind = rs.getInt("增加暗黑耐性");
        int double_score = rs.getInt("阵营积分加倍");
        int removeitem = rs.getInt("是否删除道具");
        String type_msg = rs.getString("类型重复时给予讯息");
        L1ItemUseEX vip = new L1ItemUseEX();
        vip.set_type(type);
        vip.setItem_name(itemName);
        vip.setMessage(Message);
        vip.set_type_mod(type_mod);
        vip.set_buff_time(buff_time);
        vip.set_buff_gfx(buff_gfx);
        vip.set_buff_save(buff_save);
        vip.set_type(type);
        vip.set_cancellation(cancellation);
        vip.set_poly(poly);
        vip.set_add_str(add_str);
        vip.set_add_dex(add_dex);
        vip.set_add_con(add_con);
        vip.set_add_int(add_int);
        vip.set_add_wis(add_wis);
        vip.set_add_cha(add_cha);
        vip.set_add_ac(add_ac);
        vip.set_add_hp(add_hp);
        vip.set_add_mp(add_mp);
        vip.set_add_hpr(add_hpr);
        vip.set_add_mpr(add_mpr);
        vip.set_add_dmg(add_dmg);
        vip.set_add_hit(add_hit);
        vip.set_add_bow_dmg(add_bow_dmg);
        vip.set_add_bow_hit(add_bow_hit);
        vip.set_add_dmg_r(add_dmg_r);
        vip.set_add_magic_r(add_magic_r);
        vip.set_add_mr(add_mr);
        vip.set_add_sp(add_sp);
        vip.set_add_fire(add_fire);
        vip.set_add_wind(add_wind);
        vip.set_add_earth(add_earth);
        vip.set_add_water(add_water);
        vip.set_add_stun(add_stun);
        vip.set_add_stone(add_stone);
        vip.set_add_sleep(add_sleep);
        vip.set_add_freeze(add_freeze);
        vip.set_add_sustain(add_sustain);
        vip.set_add_blind(add_blind);
        vip.settype_msg(type_msg);
        vip.set_double_score(double_score);
        vip.set_removeitem(removeitem);
        _list.put(Integer.valueOf(item_id), vip);
        ArrayList<Integer> map = _type.get(Integer.valueOf(type));
        if (map == null) {
          map = new ArrayList<>();
          map.add(Integer.valueOf(item_id));
          _type.put(Integer.valueOf(type), map);
          continue;
        } 
        map.add(Integer.valueOf(item_id));
      } 
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      SQLUtil.close(rs);
      SQLUtil.close(pstm);
      SQLUtil.close(co);
    } 
    _log.info("载入进阶版效果道具数量: " + _list.size());
  }
  
  public boolean checkItem(int item_id) {
    return _list.containsKey(Integer.valueOf(item_id));
  }
  
  public BinaryOutputStream getOS(int item_id) {
    return _os.get(Integer.valueOf(item_id));
  }
  
  public static L1ItemUseEX getItemPro(int itemId) {
    if (_list == null)
      return null; 
    if (!_list.containsKey(Integer.valueOf(itemId)))
      return null; 
    return _list.get(Integer.valueOf(itemId));
  }
  
  public static void getSaveSkillid(L1PcInstance pc) {
    Iterator<Integer> iterator = _list.keySet().iterator();
    while (iterator.hasNext()) {
      Integer skillId = iterator.next();
      if (((L1ItemUseEX)_list.get(skillId)).is_buff_save()) {
        int timeSec = pc.getSkillEffectTimeSec(skillId.intValue());
        if (timeSec <= 0)
          continue; 
        CharBuffTable.storeBuff(pc.getId(), skillId.intValue(), timeSec);
      } 
    } 
  }
  
  public boolean add(L1PcInstance pc, int item_id, int buff_time) {
    if (!_list.containsKey(Integer.valueOf(item_id)))
      return false; 
    L1ItemUseEX value = _list.get(Integer.valueOf(item_id));
    String itemName = value.getItem_name();
    if (pc.hasSkillEffect(item_id) && value.get_type_mod() == 0) {
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(166, 
            String.valueOf(String.valueOf(itemName)) + "\\aD道具赋予时效剩余\\aE" + pc.getSkillEffectTimeSec(item_id) + "秒"));
      return false;
    } 
    if (value.get_type() != 0) {
      Iterator<Integer> iterator = ((ArrayList<Integer>)_type.get(Integer.valueOf(value.get_type()))).iterator();
      while (iterator.hasNext()) {
        Integer buff_id = iterator.next();
        if (pc.hasSkillEffect(buff_id.intValue())) {
          if (value.get_type_mod() == 0) {
            pc.sendPackets((ServerBasePacket)new S_ServerMessage(value.gettype_msg()));
            return false;
          } 
          pc.removeSkillEffect(buff_id.intValue());
        } 
      } 
    } 
    if (buff_time != 0) {
      pc.setSkillEffect(item_id, value.get_buff_time() * 1000);
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(166, "\\aD道具赋予时效剩余:\\aE" + pc.getSkillEffectTimeSec(item_id) + "秒"));
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(value.getMessage()));
    } else {
      pc.setSkillEffect(item_id, value.get_buff_time() * 1000);
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(166, "\\aD道具赋予时效剩余:\\aE" + pc.getSkillEffectTimeSec(item_id) + "秒"));
    } 
    if (value.get_buff_gfx() != 0)
      pc.sendPacketsX8((ServerBasePacket)new S_SkillSound(pc.getId(), value.get_buff_gfx())); 
    StringBuilder name = new StringBuilder();
    boolean status = false;
    boolean status2 = false;
    boolean spmr = false;
    boolean attr = false;
    if (value.getMessage() != null)
      pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\aD" + value.getMessage())); 
    if (value.get_poly() != -1) {
      if (pc.hasSkillEffect(67))
        pc.removeSkillEffect(67); 
      L1PolyMorph.doPoly((L1Character)pc, value.get_poly(), value.get_buff_time(), 1);
    } 
    if (value.get_double_score() != 0)
      pc.setdouble_score(value.get_double_score()); 
    int add_str = value.get_add_str();
    if (add_str != 0) {
      pc.addStr(add_str);
      status2 = true;
    } 
    int add_dex = value.get_add_dex();
    if (add_dex != 0) {
      pc.addDex(add_dex);
      status2 = true;
    } 
    int add_con = value.get_add_con();
    if (add_con != 0) {
      pc.addCon(add_con);
      status2 = true;
    } 
    int add_int = value.get_add_int();
    if (add_int != 0) {
      pc.addInt(add_int);
      status2 = true;
    } 
    int add_wis = value.get_add_wis();
    if (add_wis != 0) {
      pc.addWis(add_wis);
      status2 = true;
    } 
    int add_cha = value.get_add_cha();
    if (add_cha != 0) {
      pc.addCha(add_cha);
      status2 = true;
    } 
    int add_ac = value.get_add_ac();
    if (add_ac != 0) {
      pc.addAc(-add_ac);
      attr = true;
    } 
    int add_hp = value.get_add_hp();
    if (add_hp != 0) {
      pc.addMaxHp(add_hp);
      pc.sendPackets((ServerBasePacket)new S_HPUpdate(pc.getCurrentHp(), pc.getMaxHp()));
      if (pc.isInParty())
        pc.getParty().updateMiniHP(pc); 
    } 
    int add_mp = value.get_add_mp();
    if (add_mp != 0) {
      pc.addMaxMp(add_mp);
      pc.sendPackets((ServerBasePacket)new S_MPUpdate(pc.getCurrentMp(), pc.getMaxMp()));
    } 
    int add_hpr = value.get_add_hpr();
    if (add_hpr != 0)
      pc.addHpr(add_hpr); 
    int add_mpr = value.get_add_mpr();
    if (add_mpr != 0)
      pc.addMpr(add_mpr); 
    int add_dmg = value.get_add_dmg();
    if (add_dmg != 0)
      pc.addDmgup(add_dmg); 
    int add_hit = value.get_add_hit();
    if (add_hit != 0)
      pc.addHitup(add_hit); 
    int add_bow_dmg = value.get_add_bow_dmg();
    if (add_bow_dmg != 0)
      pc.addBowDmgup(add_bow_dmg); 
    int add_bow_hit = value.get_add_bow_hit();
    if (add_bow_hit != 0)
      pc.addBowHitup(add_bow_hit); 
    int add_dmg_r = value.get_add_dmg_r();
    if (add_dmg_r != 0)
      pc.addDamageReductionByArmor(add_dmg_r); 
    int add_magic_r = value.get_add_magic_r();
    if (add_magic_r != 0)
      pc.add_magic_reduction_dmg(add_magic_r); 
    int add_mr = value.get_add_mr();
    if (add_mr != 0) {
      pc.addMr(add_mr);
      spmr = true;
    } 
    int add_sp = value.get_add_sp();
    if (add_sp != 0) {
      pc.addSp(add_sp);
      spmr = true;
    } 
    int add_fire = value.get_add_fire();
    if (add_fire != 0) {
      pc.addFire(add_fire);
      attr = true;
    } 
    int add_wind = value.get_add_wind();
    if (add_wind != 0) {
      pc.addWind(add_wind);
      attr = true;
    } 
    int add_earth = value.get_add_earth();
    if (add_earth != 0) {
      pc.addEarth(add_earth);
      attr = true;
    } 
    int add_water = value.get_add_water();
    if (add_water != 0) {
      pc.addWater(add_water);
      attr = true;
    } 
    int add_stun = value.get_add_stun();
    if (add_stun != 0)
      pc.addRegistStun(add_stun); 
    int add_stone = value.get_add_stone();
    if (add_stone != 0)
      pc.addRegistStone(add_stone); 
    int add_sleep = value.get_add_sleep();
    if (add_sleep != 0)
      pc.addRegistSleep(add_sleep); 
    int add_freeze = value.get_add_freeze();
    if (add_freeze != 0)
      pc.add_regist_freeze(add_freeze); 
    int add_sustain = value.get_add_sustain();
    if (add_sustain != 0)
      pc.addRegistSustain(add_sustain); 
    int add_blind = value.get_add_blind();
    if (add_blind != 0)
      pc.addRegistBlind(add_blind); 
    pc.sendPackets((ServerBasePacket)new S_OwnCharStatus(pc));
    pc.sendPackets((ServerBasePacket)new S_OwnCharStatus2(pc));
    pc.sendPackets((ServerBasePacket)new S_OwnCharAttrDef(pc));
    pc.sendPackets((ServerBasePacket)new S_SPMR(pc));
    pc.sendPackets((ServerBasePacket)new S_ServerMessage(name.toString()));
    return true;
  }
  
  public void remove(L1PcInstance pc, int item_id) {
    L1ItemUseEX value = _list.get(Integer.valueOf(item_id));
    boolean status = false;
    boolean status2 = false;
    boolean spmr = false;
    boolean attr = false;
    String itemName = value.getItem_name();
    pc.sendPackets((ServerBasePacket)new S_ServerMessage(166, "\\aE[" + itemName + "]道具赋予时间结束"));
    StringBuilder name = new StringBuilder();
    if (value.getMessage() != null)
      pc.sendPackets((ServerBasePacket)new S_ServerMessage("\\aE" + value.getMessage() + " 效果结束")); 
    if (value.get_double_score() != 0)
      pc.setdouble_score(-value.get_double_score()); 
    int add_str = value.get_add_str();
    if (add_str != 0) {
      pc.addStr(-add_str);
      status2 = true;
    } 
    int add_dex = value.get_add_dex();
    if (add_dex != 0) {
      pc.addDex(-add_dex);
      status2 = true;
    } 
    int add_con = value.get_add_con();
    if (add_con != 0) {
      pc.addCon(-add_con);
      status2 = true;
    } 
    int add_int = value.get_add_int();
    if (add_int != 0) {
      pc.addInt(-add_int);
      status2 = true;
    } 
    int add_wis = value.get_add_wis();
    if (add_wis != 0) {
      pc.addWis(-add_wis);
      status2 = true;
    } 
    int add_cha = value.get_add_cha();
    if (add_cha != 0) {
      pc.addCha(-add_cha);
      status2 = true;
    } 
    int add_ac = value.get_add_ac();
    if (add_ac != 0) {
      pc.addAc(add_ac);
      attr = true;
    } 
    int add_hp = value.get_add_hp();
    if (add_hp != 0) {
      pc.addMaxHp(-add_hp);
      pc.sendPackets((ServerBasePacket)new S_HPUpdate(pc.getCurrentHp(), pc.getMaxHp()));
      if (pc.isInParty())
        pc.getParty().updateMiniHP(pc); 
    } 
    int add_mp = value.get_add_mp();
    if (add_mp != 0) {
      pc.addMaxMp(-add_mp);
      pc.sendPackets((ServerBasePacket)new S_MPUpdate(pc.getCurrentMp(), pc.getMaxMp()));
    } 
    int add_hpr = value.get_add_hpr();
    if (add_hpr != 0)
      pc.addHpr(-add_hpr); 
    int add_mpr = value.get_add_mpr();
    if (add_mpr != 0)
      pc.addMpr(-add_mpr); 
    int add_dmg = value.get_add_dmg();
    if (add_dmg != 0)
      pc.addDmgup(-add_dmg); 
    int add_hit = value.get_add_hit();
    if (add_hit != 0)
      pc.addHitup(-add_hit); 
    int add_bow_dmg = value.get_add_bow_dmg();
    if (add_bow_dmg != 0)
      pc.addBowDmgup(-add_bow_dmg); 
    int add_bow_hit = value.get_add_bow_hit();
    if (add_bow_hit != 0)
      pc.addBowHitup(-add_bow_hit); 
    int add_dmg_r = value.get_add_dmg_r();
    if (add_dmg_r != 0)
      pc.addDamageReductionByArmor(-add_dmg_r); 
    int add_magic_r = value.get_add_magic_r();
    if (add_magic_r != 0)
      pc.add_magic_reduction_dmg(-add_magic_r); 
    int add_mr = value.get_add_mr();
    if (add_mr != 0) {
      pc.addMr(-add_mr);
      spmr = true;
    } 
    int add_sp = value.get_add_sp();
    if (add_sp != 0) {
      pc.addSp(-add_sp);
      spmr = true;
    } 
    int add_fire = value.get_add_fire();
    if (add_fire != 0) {
      pc.addFire(-add_fire);
      attr = true;
    } 
    int add_wind = value.get_add_wind();
    if (add_wind != 0) {
      pc.addWind(-add_wind);
      attr = true;
    } 
    int add_earth = value.get_add_earth();
    if (add_earth != 0) {
      pc.addEarth(-add_earth);
      attr = true;
    } 
    int add_water = value.get_add_water();
    if (add_water != 0) {
      pc.addWater(-add_water);
      attr = true;
    } 
    int add_stun = value.get_add_stun();
    if (add_stun != 0)
      pc.addRegistStun(-add_stun); 
    int add_stone = value.get_add_stone();
    if (add_stone != 0)
      pc.addRegistStone(-add_stone); 
    int add_sleep = value.get_add_sleep();
    if (add_sleep != 0)
      pc.addRegistSleep(-add_sleep); 
    int add_freeze = value.get_add_freeze();
    if (add_freeze != 0)
      pc.add_regist_freeze(-add_freeze); 
    int add_sustain = value.get_add_sustain();
    if (add_sustain != 0)
      pc.addRegistSustain(-add_sustain); 
    int add_blind = value.get_add_blind();
    if (add_blind != 0)
      pc.addRegistBlind(-add_blind); 
    pc.sendPackets((ServerBasePacket)new S_ServerMessage(name.toString()));
    if (status2)
      pc.sendPackets((ServerBasePacket)new S_OwnCharStatus2(pc)); 
    if (attr)
      pc.sendPackets((ServerBasePacket)new S_OwnCharAttrDef(pc)); 
    if (spmr)
      pc.sendPackets((ServerBasePacket)new S_SPMR(pc)); 
  }
}
